package org.roger.index;

import java.io.File;
import java.io.IOException;

import org.apache.lucene.analysis.core.SimpleAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.IntField;
import org.apache.lucene.document.StoredField;
import org.apache.lucene.document.StringField;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.IndexableField;
import org.apache.lucene.spatial.SpatialStrategy;
import org.apache.lucene.spatial.prefix.RecursivePrefixTreeStrategy;
import org.apache.lucene.spatial.prefix.tree.GeohashPrefixTree;
import org.apache.lucene.spatial.prefix.tree.SpatialPrefixTree;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;

import com.spatial4j.core.context.SpatialContext;
import com.spatial4j.core.shape.Shape;

/**
 * 建立空间索引
 * @author luoweiyi
 */
public class SpatialLuceneIndex {
	
	private final String latField = "lat";
	private final String lngField = "lng";
	
	private SpatialStrategy strategy;
	private String indexPath;
	private SpatialContext ctx;
	private Directory directory;
	
	public SpatialLuceneIndex(String indexPath){
		this.indexPath = indexPath;
	}
	
	{
		//Typical geospatial context  
	    //These can also be constructed from SpatialContextFactory  
		this.ctx = SpatialContext.GEO;
		int maxLevels = 11;//results in sub-meter precision for geohash
		SpatialPrefixTree grid = new GeohashPrefixTree(ctx, maxLevels);
		this.strategy = new RecursivePrefixTreeStrategy(grid, "myGeoField");
		try {  
			this.directory = FSDirectory.open(new File(indexPath));  
		} catch (IOException e) {  
			e.printStackTrace();  
		}  
	}
	
//	protected void init() { 
//		//Typical geospatial context  
//	    //These can also be constructed from SpatialContextFactory  
//		this.ctx = SpatialContext.GEO;
//		int maxLevels = 11;//results in sub-meter precision for geohash
//		SpatialPrefixTree grid = new GeohashPrefixTree(ctx, maxLevels);
//		this.strategy = new RecursivePrefixTreeStrategy(grid, "myGeoField");
//		try {  
//			this.directory = FSDirectory.open(new File(indexPath));  
//		} catch (IOException e) {  
//			e.printStackTrace();  
//		}  
//	}
	
	public void index() throws IOException {
		//init();  
	    createIndex();
	}
	
	private void createIndex() throws IOException {  
	    IndexWriterConfig iwConfig = new IndexWriterConfig(Version.LATEST,new SimpleAnalyzer());  
	    IndexWriter indexWriter = new IndexWriter(directory, iwConfig);  
	    //Spatial4j is x-y order for arguments|对于参数的顺序是Longitude,Latitude  
	    indexWriter.addDocument(newSampleDocument(0, "一星大饭店",ctx.makePoint(116.430360,39.939686)));  
	    indexWriter.addDocument(newSampleDocument(1, "二星大饭店",ctx.makePoint( 116.430319,39.939702)));  
	    indexWriter.addDocument(newSampleDocument(2, "三星大饭店",ctx.makePoint(116.430459,39.939802)));  
	    indexWriter.addDocument(newSampleDocument(3, "四星大饭店", ctx.makePoint(116.430449,39.939902)));  
	    indexWriter.addDocument(newSampleDocument(4, "六星大饭店",ctx.makePoint(116.430439,39.93402)));  
	    indexWriter.addDocument(newSampleDocument(5, "七星大饭店",ctx.makePoint(116.430419,39.934102)));  
	    indexWriter.addDocument(newSampleDocument(6, "五星大饭店",ctx.makePoint(116.430429,39.934202)));  
	    indexWriter.addDocument(newSampleDocument(6, "五星大酒店",ctx.makePoint(115.430429,39.934202)));  
	    indexWriter.commit();  
	    indexWriter.close();  
	}
	
	private Document newSampleDocument(int id,String keyword, Shape... shapes) {  
	    Document doc = new Document();  
	    doc.add(new IntField("id", id, Field.Store.YES));  
	    //Potentially more than one shape in this field is supported by some  
	    // strategies; see the javadocs of the SpatialStrategy impl to see.  
	    for (Shape shape : shapes) {  
	      for (IndexableField f : strategy.createIndexableFields(shape)) {  
	        doc.add(f);  
	      }  
	      //store it too; the format is up to you  
	      doc.add(new StoredField(strategy.getFieldName(), ctx.toString(shape)));  
	    }  
	    doc.add(new StringField("keyword",keyword, Field.Store.YES));  
	    return doc;  
	} 
	
	public static void main(String[] args) {
		SpatialLuceneIndex index = new SpatialLuceneIndex("D:/lucene/spatial");
		try {
			index.index();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

}
